package io.gitee.mayan50.autoassociate.value;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.gitee.mayan50.autoassociate.annotation.OneToMany;
import io.gitee.mayan50.autoassociate.annotation.OneToOne;
import io.gitee.mayan50.autoassociate.constant.AssociateTypeEnum;

import java.lang.reflect.Field;

/**
 * 单个变量关联实现实体类
 */
public class AssociateFieldEntity<E> {

    private final AssociateTypeEnum type;

    private OneToOne oneToOne;

    private OneToMany oneToMany;

    private final BaseMapper<E> baseMapper;

    private Object value;

    public AssociateFieldEntity(OneToOne oneToOne, BaseMapper<E> baseMapper) {
        this.type = AssociateTypeEnum.ONE_TO_ONE;
        this.oneToOne = oneToOne;
        this.baseMapper = baseMapper;
    }

    public AssociateFieldEntity(OneToMany oneToMany, BaseMapper<E> baseMapper) {
        this.type = AssociateTypeEnum.ONE_TO_MANY;
        this.oneToMany = oneToMany;
        this.baseMapper = baseMapper;
    }

    public AssociateFieldEntity<E> setValue(Object value) {
        this.value = value;
        return this;
    }

    public boolean isOneToOne() {
        return this.type == AssociateTypeEnum.ONE_TO_ONE;
    }

    public String column() {
        if (isOneToOne()) return oneToOne.column();
        return oneToMany.column();
    }

    public String sql() {
        if (isOneToOne()) return oneToOne.sql();
        return oneToMany.sql();
    }

    public int deep() {
        if (isOneToOne()) return oneToOne.deep();
        return oneToMany.deep();
    }

    public String[] condition() {
        if (isOneToOne()) return oneToOne.condition();
        return oneToMany.condition();
    }

    private <T> void setOneToOneValue(T t, Field field) throws IllegalAccessException {
        field.set(t, baseMapper.selectOne(new QueryWrapper<E>().eq(oneToOne.associateColumn(), value)));
    }

    private <T> void setOneToManyValue(T t, Field field) throws IllegalAccessException {
        field.set(t, baseMapper.selectList(new QueryWrapper<E>().eq(oneToMany.associateColumn(), value)));
    }

    public <T> void setField(T t, Field field) throws IllegalAccessException {
        if (isOneToOne()) setOneToOneValue(t, field);
        else setOneToManyValue(t, field);
    }

}
